﻿using Microsoft.Build.Construction;
using Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;

namespace Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.Models
{
    [Obsolete]
    public class MSBuildProject
    {
        private static readonly string FxCopCmdPathRegistry = @"$(Registry:HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\10.0\DialogPage\Sasa.QualityTools.CodeAnalysis.FxCopIntegrator.GeneralOptionPageData@FxCopCmdPath)";

        private static readonly string CodeAnalyisOnBuildCondition = "'$(BuildingInsideVisualStudio)' == 'true' And '$(EnableCodeAnalysisOnBuild)' == 'true' And Exists('$(TargetPath)')";

        private static readonly string BuildBreakCondition = "'$(BuildingInsideVisualStudio)' == 'true' And '$(EnableCodeAnalysisOnBuild)' == 'true' And !Exists('$(TargetPath).lastcodeanalysissucceeded')";

        private ProjectRootElement root;


        public CodeAnalysisConfiguration Configuration { get; set; }

        public ICollection<string> DependencyDirectories { get; private set; }

        public bool EnableCodeAnalysisOnBuild { get; set; }


        private MSBuildProject(string path)
        {
            DependencyDirectories = new List<string>();
            root = ProjectRootElement.Open(path);
            EnableCodeAnalysisOnBuild = Convert.ToBoolean(GetPropertyValue("EnableCodeAnalysisOnBuild"));
        }


        public static MSBuildProject Load(string path)
        {
            return new MSBuildProject(path);
        }

        public void Save()
        {
            SetPropertyValue("EnableCodeAnalysisOnBuild", EnableCodeAnalysisOnBuild.ToString());
            SetPropertyValue("FxCopCmdPath", FxCopCmdPathRegistry);
            SetPropertyValue("RuleSetDir", Path.Combine(Environment.GetEnvironmentVariable("VS100COMNTOOLS"), "..", "..", "Team Tools", "Static Analysis Tools", "Rule Sets") + Path.DirectorySeparatorChar);

            var target = FindOrCreateAfterBuildTarget(root);
            var exec = FindCodeAnalysisOnBuildTask(target);
            if (exec == null)
            {
                exec = target.AddTask("Exec");
                exec.Condition = CodeAnalyisOnBuildCondition;
            }
            exec.SetParameter("Command", CreateAfterBuildCommand(Configuration, DependencyDirectories));

            root.Save();
        }

        private string CreateAfterBuildCommand(CodeAnalysisConfiguration configuration, IEnumerable<string> dependencyDirectories)
        {
            return null;
            // TODO:
            //return @"""$(FxCopCmdPath)"" " + FxCopCmdOptionBuilder.Build(configuration, dependencyDirectories);
        }

        private ProjectTargetElement FindOrCreateAfterBuildTarget(ProjectRootElement root)
        {
            var target = root.Targets.FirstOrDefault(o => o.Name == "AfterBuild");
            if (target == null)
            {
                target = root.AddTarget("AfterBuild");
            }
            return target;
        }

        private ProjectTaskElement FindCodeAnalysisOnBuildTask(ProjectTargetElement target)
        {
            return target.Tasks.FirstOrDefault(o => o.Name == "Exec" && o.Condition == CodeAnalyisOnBuildCondition && o.GetParameter("Command").StartsWith(@"""$(FxCopCmdPath)"" "));
        }

        private string GetPropertyValue(string name)
        {
            var property = root.Properties.FirstOrDefault(o => o.Name == name);
            return (property != null) ? property.Value : null;
        }

        private void SetPropertyValue(string name, string value)
        {
            var property = root.Properties.FirstOrDefault(o => o.Name == name);
            if (property == null)
            {
                root.AddProperty(name, value);
            }
            else
            {
                property.Value = value;
            }
        }
    }
}
